import { useEffect, useRef, useState } from 'react'
import moment from 'moment'
import { useStrategyBacktest, BASE_CAPITAL, useTradeMarkers } from './index'

function update (chart, data) {
}

const comment = () => {
  return (
    <div>
      利用零滞后指数移动平均（ZLEMA）和波动带识别趋势：突破上方波动带视为多头拐点，跌破下方波动带视为空头拐点，自动完成买卖。
    </div>
  )
}

const DEFAULT_LENGTH = 70
const DEFAULT_MULT = 1.2
const INTERVAL_KEY = 'zeroLagInterval'

function calculateZeroLagTrend (data, length = DEFAULT_LENGTH, mult = DEFAULT_MULT) {
  const result = []
  const zlemaList = []
  const volatilityList = []
  const trendList = []
  const lag = Math.floor((length - 1) / 2)
  const emaAlpha = 2 / (length + 1)
  const atrAlpha = 1 / length
  const atrWindow = Math.max(length * 3, length)
  const atrQueue = []

  let ema = null
  let atr = null
  let prevClose = data[0]?.close ?? 0

  for (let i = 0; i < data.length; i++) {
    const candle = data[i]
    const src = candle.close
    const lagSrc = i >= lag ? data[i - lag].close : src
    const adjusted = src + (src - lagSrc)
    ema = ema == null ? adjusted : (emaAlpha * adjusted + (1 - emaAlpha) * ema)
    zlemaList.push(ema)

    const high = candle.high
    const low = candle.low
    const tr = Math.max(
      high - low,
      Math.abs(high - prevClose),
      Math.abs(low - prevClose)
    )
    prevClose = candle.close
    atr = atr == null ? tr : (atr + (tr - atr) * atrAlpha)
    atrQueue.push(atr)
    if (atrQueue.length > atrWindow) {
      atrQueue.shift()
    }
    const volatility = Math.max(...atrQueue) * mult
    volatilityList.push(volatility)

    let trend = trendList[i - 1] ?? 0
    if (candle.close > ema + volatility) {
      trend = 1
    } else if (candle.close < ema - volatility) {
      trend = -1
    }
    trendList.push(trend)

    result.push({
      zlema: ema,
      volatility,
      trend
    })
  }
  return { zlemaList, volatilityList, trendList, result }
}

const ZeroLagTools = (props) => {
  const [started, setStarted] = useState(false)
  const [autoRun, setAutoRun] = useState(false)
  const [finished, setFinished] = useState(false)
  const [data, setData] = useState([])
  const [currentIndex, setCurrentIndex] = useState(0)
  const [holding, setHolding] = useState(false)
  const [intervalMs, setIntervalMs] = useState(() => {
    if (typeof window !== 'undefined') {
      const stored = localStorage.getItem(INTERVAL_KEY)
      if (stored) {
        const val = Number(stored)
        if (!Number.isNaN(val) && val >= 100 && val <= 5000) {
          return val
        }
      }
    }
    return 500
  })
  const intervalRef = useRef(intervalMs)
  const autoTimerRef = useRef(null)
  const tradeInfoRef = useRef({
    active: false,
    entryPrice: 0,
    entryIndex: -1,
    overlayId: null
  })
  const overlaysRef = useRef([])
  const zlemaOverlaysRef = useRef([]) // 用于存储 ZLEMA 相关的 overlay（填充、标记等）
  const { addTradeMarker, redrawTradeMarkers, clearTradeMarkers } = useTradeMarkers(props.chart)
  const zlemaIndicatorIdRef = useRef(null) // ZLEMA 指标的 ID
  const {
    equityHistory,
    recordEquity,
    registerTrade,
    reset: resetBacktest,
    finalize,
    SummaryModal
  } = useStrategyBacktest()

  // 将 equityHistory 传递给父组件
  useEffect(() => {
    if (props.onEquityHistoryChange) {
      props.onEquityHistoryChange(equityHistory)
    }
  }, [equityHistory])

  useEffect(() => {
    return () => {
      if (autoTimerRef.current) {
        clearInterval(autoTimerRef.current)
      }
    }
  }, [])

  useEffect(() => {
    intervalRef.current = intervalMs
    if (typeof window !== 'undefined') {
      localStorage.setItem(INTERVAL_KEY, String(intervalMs))
    }
  }, [intervalMs])

  useEffect(() => {
    if (autoTimerRef.current) {
      clearInterval(autoTimerRef.current)
    }
    if (started && autoRun && !finished) {
      autoTimerRef.current = setInterval(() => {
        nextStep()
      }, intervalRef.current)
    }
    return () => {
      if (autoTimerRef.current) {
        clearInterval(autoTimerRef.current)
      }
    }
  }, [autoRun, started, finished, data, currentIndex])

  const removeTradeOverlay = () => {
    if (tradeInfoRef.current.overlayId && props.chart?.current) {
      try {
        props.chart.current.removeOverlay(tradeInfoRef.current.overlayId)
      } catch (e) {
        // ignore
      }
    }
    tradeInfoRef.current.overlayId = null
  }

  const clearAllOverlays = () => {
    if (props.chart?.current) {
      overlaysRef.current.forEach(id => {
        try {
          props.chart.current.removeOverlay(id)
        } catch (e) {
          // ignore
        }
      })
      zlemaOverlaysRef.current.forEach(id => {
        try {
          props.chart.current.removeOverlay(id)
        } catch (e) {
          // ignore
        }
      })
      // 清除 ZLEMA 指标
      if (zlemaIndicatorIdRef.current) {
        try {
          props.chart.current.removeIndicator(zlemaIndicatorIdRef.current)
        } catch (e) {
          // ignore
        }
        zlemaIndicatorIdRef.current = null
      }
    }
    overlaysRef.current = []
    zlemaOverlaysRef.current = []
    removeTradeOverlay()
    clearTradeMarkers() // 清除买卖标记
  }

  // 使用统一的买卖标记管理器，addTradeMarker 已从 useTradeMarkers 获取

  const refreshTradeOverlay = (actualData) => {
    const info = tradeInfoRef.current
    if (!info.active || !props.chart?.current) {
      removeTradeOverlay()
      return
    }
    if (info.entryIndex < 0 || info.entryIndex >= actualData.length) {
      removeTradeOverlay()
      return
    }
    const segment = actualData.slice(info.entryIndex)
    if (!segment.length) {
      removeTradeOverlay()
      return
    }
    // 使用全部数据的最高价和最低价，而不是只使用 segment 的价格
    const maxHigh = Math.max(...actualData.map(bar => bar.high))
    const minLow = Math.min(...actualData.map(bar => bar.low))
    const latestClose = segment[segment.length - 1].close
    const color = latestClose >= info.entryPrice ? 'rgba(255,22,22,0.15)' : 'rgba(13,190,28,0.15)'
    removeTradeOverlay()
    info.overlayId = props.chart.current.createOverlay({
      name: 'rect',
      styles: {
        polygon: { color }
      },
      points: [
        { timestamp: segment[0].timestamp, value: maxHigh },
        { timestamp: segment[segment.length - 1].timestamp, value: minLow }
      ]
    })
  }

  const loadRandomDataset = async () => {
    const stocks = props.stocks ?? []
    if (!stocks.length) return
    const tradable = stocks.filter(stock => {
      return ((stock.code.startsWith('60') && stock.code.endsWith('SH')) ||
        (stock.code.startsWith('00') && stock.code.endsWith('SZ')) ||
        (stock.code.startsWith('30') && stock.code.endsWith('SZ'))) &&
        !stock.name.includes('ST')
    })
    if (!tradable.length) return
    const randomStock = tradable[Math.floor(Math.random() * tradable.length)]
    let dates = (props.dates ?? []).filter(date => {
      return date / 1000 >= randomStock.open && moment.unix(date / 1000).year() <= 2021
    })
    if (!dates.length) return
    const randomDate = dates[Math.floor(Math.random() * dates.length)]
    const dailyData = await props.getKlines(randomStock.code, '1d', randomDate, 600)
    if (!dailyData || !dailyData.length) return
    const startIndex = Math.min(Math.floor(dailyData.length / 2), dailyData.length - 1)
    const initialData = dailyData.slice(0, startIndex)
    setData(dailyData)
    setCurrentIndex(startIndex)
    setFinished(false)
    setHolding(false)
    resetBacktest()
    clearAllOverlays()
    tradeInfoRef.current = {
      active: false,
      entryPrice: 0,
      entryIndex: -1,
      overlayId: null
    }
    if (props.trader?.reset) {
      props.trader.reset()
    }
    applyChart(initialData)
    const initialTimestamp = initialData.length ? initialData[initialData.length - 1].timestamp : Date.now()
    recordEquity(initialTimestamp, props.trader?.equity ?? BASE_CAPITAL)
    setStarted(true)
    props.setInfoDisplay(false)
  }

  const createGhostBar = (last) => {
    if (!last) return null
    return {
      open: last.close,
      close: last.close,
      high: last.close,
      low: last.close,
      volume: 0,
      amount: 0,
      timestamp: last.timestamp + 24 * 60 * 60 * 1000
    }
  }

  // 绘制 ZLEMA 相关的图形（填充区域和趋势标记）
  // 注意：ZLEMA 线、上下轨线通过 indicator 绘制，这里只用 overlay 绘制填充和标记
  const drawZLEMAOverlays = (actualData) => {
    if (!props.chart?.current || actualData.length < 2) return
    
    // 清除之前的 ZLEMA overlay（填充和标记）
    zlemaOverlaysRef.current.forEach(id => {
      try {
        props.chart.current.removeOverlay(id)
      } catch (e) {
        // ignore
      }
    })
    zlemaOverlaysRef.current = []

    const { zlemaList, volatilityList, trendList } = calculateZeroLagTrend(actualData)
    
    // 计算 ATR 用于三角形标记位置
    const calcATR = (data, period = 5) => {
      if (data.length < period) return 0
      let sum = 0
      for (let i = data.length - period; i < data.length; i++) {
        if (i === 0) continue
        const prev = data[i - 1]
        const curr = data[i]
        const tr = Math.max(
          curr.high - curr.low,
          Math.abs(curr.high - prev.close),
          Math.abs(curr.low - prev.close)
        )
        sum += tr
      }
      return sum / period
    }
    
    const atr5 = calcATR(actualData, 5)
    
    // 绘制填充区域和趋势标记
    for (let i = 1; i < actualData.length; i++) {
      const candle = actualData[i]
      const prevCandle = actualData[i - 1]
      const trend = trendList[i] ?? 0
      const prevTrend = trendList[i - 1] ?? 0
      const zlema = zlemaList[i]
      const volatility = volatilityList[i]
      
      if (zlema == null || volatility == null) continue
      
      // 绘制填充区域（fill）
      if (trend === 1 && zlema != null && volatility != null) {
        // 看涨填充：ZLEMA 到下轨之间
        try {
          const fillId = props.chart.current.createOverlay({
            name: 'rect',
            styles: {
              polygon: {
                color: 'rgba(0, 255, 187, 0.2)', // 青色填充，透明度 80
                style: 'fill'
              }
            },
            points: [
              { timestamp: prevCandle.timestamp, value: zlema },
              { timestamp: candle.timestamp, value: zlema },
              { timestamp: candle.timestamp, value: zlema - volatility },
              { timestamp: prevCandle.timestamp, value: zlema - volatility }
            ]
          })
          if (fillId) zlemaOverlaysRef.current.push(fillId)
        } catch (e) {
          console.warn('Failed to create bullish fill:', e)
        }
      } else if (trend === -1 && zlema != null && volatility != null) {
        // 看跌填充：ZLEMA 到上轨之间
        try {
          const fillId = props.chart.current.createOverlay({
            name: 'rect',
            styles: {
              polygon: {
                color: 'rgba(255, 17, 0, 0.2)', // 红色填充，透明度 80
                style: 'fill'
              }
            },
            points: [
              { timestamp: prevCandle.timestamp, value: zlema },
              { timestamp: candle.timestamp, value: zlema },
              { timestamp: candle.timestamp, value: zlema + volatility },
              { timestamp: prevCandle.timestamp, value: zlema + volatility }
            ]
          })
          if (fillId) zlemaOverlaysRef.current.push(fillId)
        } catch (e) {
          console.warn('Failed to create bearish fill:', e)
        }
      }
      
      // 绘制 ZLEMA 趋势标记（三角形）
      // ZLEMA 连续上涨 5 根：底部绿色向上三角形
      if (i >= 4) {
        const zlemaUpTrend = zlemaList[i] > zlemaList[i - 1] &&
                            zlemaList[i - 1] > zlemaList[i - 2] &&
                            zlemaList[i - 2] > zlemaList[i - 3] &&
                            zlemaList[i - 3] > zlemaList[i - 4]
        
        if (zlemaUpTrend) {
          try {
            const triangleId = props.chart.current.createOverlay({
              name: 'simpleAnnotation',
              extendData: '▲',
              points: [{ timestamp: candle.timestamp, value: candle.low - atr5 * 0.5 }],
              styles: {
                annotation: {
                  text: {
                    color: '#00ff00', // 绿色
                    backgroundColor: 'rgba(0, 255, 0, 0.2)',
                    borderColor: '#00ff00'
                  }
                }
              }
            })
            if (triangleId) zlemaOverlaysRef.current.push(triangleId)
          } catch (e) {
            console.warn('Failed to create uptrend marker:', e)
          }
        }
        
        // ZLEMA 连续下跌 5 根：顶部红色向下三角形
        const zlemaDownTrend = zlemaList[i] < zlemaList[i - 1] &&
                              zlemaList[i - 1] < zlemaList[i - 2] &&
                              zlemaList[i - 2] < zlemaList[i - 3] &&
                              zlemaList[i - 3] < zlemaList[i - 4]
        
        if (zlemaDownTrend) {
          try {
            const triangleId = props.chart.current.createOverlay({
              name: 'simpleAnnotation',
              extendData: '▼',
              points: [{ timestamp: candle.timestamp, value: candle.high + atr5 * 0.5 }],
              styles: {
                annotation: {
                  text: {
                    color: '#ff0000', // 红色
                    backgroundColor: 'rgba(255, 0, 0, 0.2)',
                    borderColor: '#ff0000'
                  }
                }
              }
            })
            if (triangleId) zlemaOverlaysRef.current.push(triangleId)
          } catch (e) {
            console.warn('Failed to create downtrend marker:', e)
          }
        }
      }
    }
  }

  // 确保 ZLEMA 指标存在（回测时强制显示，不受首页 toggle 控制）
  const ensureZLEMAIndicator = () => {
    if (!props.chart?.current) return
    
    // 检查指标是否已存在
    if (zlemaIndicatorIdRef.current) {
      // 如果已存在，确保参数正确
      try {
        const params = [DEFAULT_LENGTH, DEFAULT_MULT]
        props.chart.current.overrideIndicator(zlemaIndicatorIdRef.current, {
          calcParams: params
        })
      } catch (e) {
        // ignore
      }
      return
    }
    
    // 创建 ZLEMA 指标（在主图上，回测时始终显示）
    try {
      const indicatorId = props.chart.current.createIndicator('ZLEMA', false, { 
        id: 'candle_pane',
        calcParams: [DEFAULT_LENGTH, DEFAULT_MULT]
      })
      if (indicatorId) {
        zlemaIndicatorIdRef.current = indicatorId
      }
    } catch (e) {
      console.warn('Failed to create ZLEMA indicator:', e)
    }
  }

  const applyChart = (actualData) => {
    if (!props.chart?.current) return
    if (!actualData.length) {
      props.chart.current.applyNewData([])
      props.onDataApplied?.([])
      return
    }
    const ghost = createGhostBar(actualData[actualData.length - 1])
    const chartData = ghost ? [...actualData, ghost] : [...actualData]
    props.chart.current.applyNewData(chartData)
    
    // 确保 ZLEMA 指标存在
    ensureZLEMAIndicator()
    
    if (props.indicatorStrategies) {
      for (const indicatorStrategy of props.indicatorStrategies) {
        if (indicatorStrategy.reset) {
          indicatorStrategy.reset(props.chart.current)
        }
        indicatorStrategy.update(props.chart.current, chartData)
      }
    }
    
    // applyNewData 清除了所有 overlay，需要重新绘制买卖标记
    redrawTradeMarkers()
    
    // 绘制 ZLEMA 相关的图形（填充和标记）
    drawZLEMAOverlays(actualData)
    
    props.onDataApplied?.(chartData)
    const latest = actualData[actualData.length - 1]
    props.setPrice?.(latest.close)
  }

  const evaluateSignals = (actualData) => {
    if (actualData.length < 2) return
    const { trendList } = calculateZeroLagTrend(actualData)
    const idx = actualData.length - 1
    const prevTrend = idx > 0 ? trendList[idx - 1] : 0
    const currTrend = trendList[idx]
    const candle = actualData[idx]
    let traded = false
    if (prevTrend <= 0 && currTrend > 0) {
        props.trader.buy(candle.close)
        setHolding(true)
        addTradeMarker(candle, 'buy', candle.close)
      tradeInfoRef.current = {
        active: true,
        entryPrice: candle.close,
        entryTimestamp: candle.timestamp,
        entryIndex: idx,
        overlayId: tradeInfoRef.current.overlayId
      }
      traded = true
    } else if (prevTrend >= 0 && currTrend < 0) {
      if (holding) {
        // 在卖出前保存成本基础，用于计算准确的收益率
        const avgCostPrice = props.trader.sell(candle.close) || tradeInfoRef.current.entryPrice || candle.close
        setHolding(false)
        addTradeMarker(candle, 'sell', candle.close)
        if (tradeInfoRef.current.overlayId && props.chart?.current) {
          overlaysRef.current.push(tradeInfoRef.current.overlayId)
        }
        // 使用实际的平均成本价计算收益率
        const profitRatio = (candle.close - avgCostPrice) / avgCostPrice
        registerTrade(profitRatio, avgCostPrice, candle.close)
        console.log('✅ 执行卖出:', {
          entryPrice: tradeInfoRef.current.entryPrice,
          avgCostPrice,
          exitPrice: candle.close,
          profitRatio,
          profitPercent: (profitRatio * 100).toFixed(2) + '%',
          timestamp: candle.timestamp
        })
        tradeInfoRef.current = {
          active: false,
          entryPrice: 0,
          entryTimestamp: null,
          entryIndex: -1,
          overlayId: null
        }
        traded = true
      }
    }
    if (!traded) {
      props.trader.hold(candle.close)
    }
    if (tradeInfoRef.current.active) {
      refreshTradeOverlay(actualData)
    }
  }

  const nextStep = () => {
    if (!started || finished) return
    const nextIndex = Math.min(currentIndex + 1, data.length)
    if (nextIndex > data.length) return
    const actualData = data.slice(0, nextIndex)
    applyChart(actualData)
    evaluateSignals(actualData)
    const lastTimestamp = actualData.length ? actualData[actualData.length - 1].timestamp : Date.now()
    recordEquity(lastTimestamp, props.trader?.equity ?? BASE_CAPITAL)
    setCurrentIndex(nextIndex)
    if (nextIndex >= data.length) {
      // 回测结束时，如果有持仓，强制平仓并记录交易
      // 使用 tradeInfoRef.current.active 而不是 holding 状态，避免状态异步更新问题
      if (tradeInfoRef.current.active && tradeInfoRef.current.entryPrice) {
        const lastCandle = actualData[actualData.length - 1]
        if (lastCandle) {
          // 在卖出前保存成本基础，用于计算准确的收益率
          const avgCostPrice = props.trader.sell(lastCandle.close) || tradeInfoRef.current.entryPrice || lastCandle.close
          setHolding(false)
          addTradeMarker(lastCandle, 'sell', lastCandle.close)
          // 使用实际的平均成本价计算收益率
          const profitRatio = (lastCandle.close - avgCostPrice) / avgCostPrice
          registerTrade(profitRatio, avgCostPrice, lastCandle.close)
          console.log('✅ 回测结束强制平仓:', {
            entryPrice: tradeInfoRef.current.entryPrice,
            avgCostPrice,
            exitPrice: lastCandle.close,
            profitRatio,
            profitPercent: (profitRatio * 100).toFixed(2) + '%',
            timestamp: lastCandle.timestamp
          })
          tradeInfoRef.current = {
            active: false,
            entryPrice: 0,
            entryTimestamp: null,
            entryIndex: -1,
            overlayId: null
          }
          // 强制平仓后，等待状态更新再 finalize
          setTimeout(() => {
            setFinished(true)
            setAutoRun(false)
            finalize()
          }, 0)
          return // 提前返回，避免重复执行 finalize
        }
      }
      // 没有持仓，直接 finalize
      setFinished(true)
      setAutoRun(false)
      finalize()
    }
  }

  const endBacktest = () => {
    if (autoTimerRef.current) {
      clearInterval(autoTimerRef.current)
    }
    clearAllOverlays()
    window.location.reload()
  }

  const stepDisabled = !started || finished
  const autoDisabled = !started || finished

  return (
    <>
      {SummaryModal}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        <div style={{ display: 'flex', flexDirection: 'row', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
          {!started && (
            <button onClick={loadRandomDataset}>开始回测</button>
          )}
          {started && (
          <>
            <button disabled={stepDisabled} onClick={nextStep}>步进</button>
            <button
              disabled={autoDisabled}
              onClick={() => {
                if (finished) return
                setAutoRun(prev => !prev)
              }}
            >
              {autoRun ? '停止自动' : '自动'}
            </button>
            <div style={{display: 'flex', alignItems: 'center', gap: 6}}>
              <div style={{color: 'rgba(255,255,255,0.65)', fontSize: 12}}>速度</div>
              <input
                type="range"
                min={100}
                max={5000}
                step={100}
                value={intervalMs}
                onChange={e => setIntervalMs(Number(e.target.value))}
                style={{width: 160}}
              />
              <div style={{minWidth: 50, textAlign: 'right', color: '#0dd697', fontSize: 12}}>{(intervalMs / 1000).toFixed(1)}s</div>
            </div>
            <button onClick={endBacktest}>结束</button>
          </>
        )}
      </div>
      </div>
    </>
  )
}

export default {
  update,
  name: '零滞后趋势',
  comment,
  Tools: ZeroLagTools
}
